import base64
import urllib
import requests
import json
import cv2
from timecacu import getTimer


# 根据输入的照片，找出人脸。这里不做人脸识别，只框出人脸。人脸的识别用单独函数来做相似度匹配。
# 人脸的检测调用百度API完成。
def face_detect(access, image, groupid="", max_face_num=10,match_threshold=30):
    content = get_file_content_as_base64(image, False)
    if groupid == "":
        url = "https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=" + access
        payload = json.dumps({
            "image": content,
            "image_type": "BASE64",
            "max_face_num": max_face_num
        })
    else:
        url = "https://aip.baidubce.com/rest/2.0/face/v3/multi-search?access_token=" + access
        payload = json.dumps({
            "group_id_list": groupid,
            "image": content,
            "image_type": "BASE64",
            "max_face_num": max_face_num,
            "match_threshold": match_threshold,
            "quality_control": "NORMAL"
        })

    headers = {
        'Content-Type': 'application/json'
    }
    response = requests.request("POST", url, headers=headers, data=payload)
    return response.text

# 将facelist的信息绘制到图像上。
def draw_face_rect(imagefile, facejson,min_size=20):
    face_dict = json.loads(facejson)
    # 如果face_dict中的error_code大于0，则说明出错
    if face_dict["error_code"] > 0:
        return None
    facelist = face_dict["result"]["face_list"]
    image = cv2.imread(imagefile)
    for face in facelist:
        x = int(face["location"]["left"])
        y = int(face["location"]["top"])
        w = face["location"]["width"]
        h = face["location"]["height"]
        if w < min_size or h < min_size:
            continue
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
        # 如果face中有user_list，则取出uid
        if "user_list" in face:
            if len(face["user_list"]) == 0:
                continue
            uid = face["user_list"][0]["user_id"]
            #groupid = face["user_list"][0]["group_id"]
            cv2.putText(image, uid, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

    return image


import os
def main():
    checkface = True
    match_pic = False
    picdir = "picture"
    resultdir = "result"
    # 如果resultdir未曾存在，则创建
    if not os.path.exists(resultdir):
        os.mkdir(resultdir)
    # 遍历picdir中所有.jpg结尾的文件
    for filename in os.listdir(picdir):
        if filename.endswith(".jpg"):
            imagefile = os.path.join(picdir, filename)
            # 将imagefile的jpg去掉，替换为_result.json
            jsonfile = os.path.join(picdir, filename.replace(".jpg", "_result.json"))
            result_img =  os.path.join(resultdir, filename.replace(".jpg", "_result.jpg"))
            if checkface:
                print(f"调用模型检测图片：{imagefile}")
                if match_pic:
                    groupid="zc_club"
                else:
                    groupid = ""
                face_json = face_detect(imagefile, groupid=groupid, max_face_num=10, match_threshold=20)
                with open(jsonfile, "w") as f:
                    f.write(face_json)
           # 读取文件系统中的识别结果。这里的uid还需要做姓名的匹配才行。
            with open(jsonfile, "r") as f:
                face_json = f.read()
                image = draw_face_rect(imagefile, face_json)
                if image is None:
                    continue
                cv2.imwrite(result_img, image)
                print(f"绘制检测结果：{result_img}")



def get_file_content_as_base64(path, urlencoded=False):
    """
    获取文件base64编码
    :param path: 文件路径
    :param urlencoded: 是否对结果进行urlencoded
    :return: base64编码信息
    """
    with open(path, "rb") as f:
        content = base64.b64encode(f.read()).decode("utf8")
        if urlencoded:
            content = urllib.parse.quote_plus(content)
    return content


def get_access_token(API_KEY, SECRET_KEY):
    """
    使用 AK，SK 生成鉴权签名（Access Token）
    :return: access_token，或是None(如果错误)
    """
    url = "https://aip.baidubce.com/oauth/2.0/token"
    params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
    return str(requests.post(url, params=params).json().get("access_token"))


# 根据输入的照片，找出人脸。这里不做人脸识别，只框出人脸。人脸的识别用单独函数来做相似度匹配。
# 人脸的检测调用百度API完成。
def detect(url, image_content,max_face_num=3):
    payload = json.dumps({
        "image": image_content,
        "image_type": "BASE64",
        "max_face_num": max_face_num
    })

    headers = {
        'Content-Type': 'application/json'
    }
    response = requests.request("POST", url, headers=headers, data=payload)
    return response.text


def get_url(API_KEY, SECRET_KEY):
    access_token = get_access_token(API_KEY, SECRET_KEY)
    url = "https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=" + access_token
    return url
def captureFaceVideo(video):
    cap = cv2.VideoCapture(video)
    API_KEY = "iy4iz8zGcwcGLO4mn3msFxGO"
    SECRET_KEY = "gXhu5nGtRLot88ID978y7D0E4Gtiogyw"
    url = get_url(API_KEY, SECRET_KEY)
    t = getTimer("baidu_rec")
    count = 1
    while True:
        # 读取视频帧
        ret, frame = cap.read()
        # 将图像缩小到1/4
        gray = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
        t.start()
        #将gray这个cv2的图像直接转为base64编码
        _, buffer = cv2.imencode('.jpg', gray)
        image_base64_bytes = base64.b64encode(buffer)
        image_content = image_base64_bytes.decode('utf-8')
        # 使用级联分类器检测人脸
        face_json = detect(url, image_content,max_face_num=3)
        t.end()
        face_dict = json.loads(face_json)
        facelist = face_dict["result"]["face_list"]
        for face in facelist:
            x = int(face["location"]["left"])*4
            y = int(face["location"]["top"])*4
            w = face["location"]["width"]*4
            h = face["location"]["height"]*4
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
        # 将frame保存到本地
        cv2.imwrite("./result/face_" + str(count) + ".jpg", frame)
        cv2.imshow('Face Detection', frame)
        # 按下q键退出
        count = count + 1
        if count > 50:
            break
    t.show()
    # 释放资源
    #cap.release()
    #cv2.destroyAllWindows()



captureFaceVideo(0)